|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 00016 #include "Compile_Options.h" 00017 #include "derivative.h" 00018 #include "ADC.h" 00019 #include <limits.h> 00020 /* 00021 ****************************************************************************** 00022 * constants 00023 ****************************************************************************** 00024 */ 00026 const ADC_t catADCInstanceList[] = 00027 { 00028 &ADC_0, &ADC_1 00029 }; 00030 /* 00031 ****************************************************************************** 00032 * Globals 00033 ****************************************************************************** 00034 */ 00036 uint16_t* gpu16ADCResults[(ADC_NO_MODULES * (ADC_CH_MAX + 1u))]; 00038 uint16_t gau16ADCChToRead[ADC_NO_MODULES]; 00039 00040 /* 00041 ****************************************************************************** 00042 * Function : u8fnADCConvert() 00043 ****************************************************************************** 00044 */ 00045 uint8_t u8fnADCConvert(const uint8_t cu8ADCInstance, 00046 const uint8_t cu8ADCCh, uint16_t* pu16Result) 00047 { 00048 uint8_t u8Status; 00049 ADCChConfig_t tADCChConfig; 00050 00051 /* Disable any on-going ADC conversion */ 00052 u8Status = u8fnADCNormalConversionEnable(cu8ADCInstance, CLEAR); 00053 if(CLEAR == u8Status) 00054 { 00055 /* Configure ADC channel */ 00056 tADCChConfig.P.ChIsrEn = TRUE; 00057 tADCChConfig.P.ChDMAEn = CLEAR; 00058 tADCChConfig.P.Instance = cu8ADCInstance; 00059 tADCChConfig.P.Channel = cu8ADCCh; 00060 u8Status = u8fnADCChannelConfig(&tADCChConfig, pu16Result); 00061 00062 if(CLEAR == u8Status) 00063 { 00064 /* Trigger a conversion */ 00065 u8Status = u8fnADCNormalConversionEnable(cu8ADCInstance, TRUE); 00066 /* We'll exit now. Result shall be ready when ADC is done. */ 00067 /* If the ADC is in SCAN mode, no need to redo this */ 00068 } 00069 } 00070 else 00071 { 00072 /* In this particular case, status is already set to something. */ 00073 } 00074 return (u8Status); 00075 } 00076 /* 00077 ****************************************************************************** 00078 * u8fnADCConfig 00079 ****************************************************************************** 00080 */ 00081 uint8_t u8fnADCConfig(uint8_t u8Instance, ADCConfig_t* ptADCConfig) 00082 { 00083 /* Declare local variables */ 00084 uint8_t u8Status; 00085 ADC_t tMyADC; 00086 00087 /* Init local variables */ 00088 u8Status = CLEAR; 00089 tMyADC = catADCInstanceList[u8Instance]; 00090 00091 /* Verify that the selected instance is valid */ 00092 if (CLEAR != tMyADC) 00093 { 00094 /* Clear any previous settings to go read a particular channel */ 00095 gau16ADCChToRead[u8Instance] = CLEAR; 00096 00097 /* Force any ongoing operation to stop */ 00098 tMyADC->MCR.B.NSTART = CLEAR; 00099 00100 /* Force the ADC into low power mode */ 00101 tMyADC->MCR.B.PWDN = TRUE; 00102 00103 /* Configure according to passed parameter tADCConfig */ 00104 /* Start with general config */ 00105 /* Enable or disable an existing result to be overwritten */ 00106 tMyADC->MCR.B.OWREN = ptADCConfig->P.OverWriteEn; 00107 /* Choose which alignment will be used */ 00108 tMyADC->MCR.B.WLSIDE = ptADCConfig->P.LeftAligned; 00109 /* Select between one-shot and scan modes */ 00110 tMyADC->MCR.B.MODE = ptADCConfig->P.ScanModeEn; 00111 /* Enable or disable the Cross-triggering unit */ 00112 tMyADC->MCR.B.CTUEN = ptADCConfig->P.CTUEn; 00113 /* Enable or disable the power-saving auto-clock shut-off */ 00114 tMyADC->MCR.B.ACK0 = ptADCConfig->P.AutoClockEn; 00115 /* Select clocking speed (divide by half or not */ 00116 tMyADC->MCR.B.ADCLKSEL = ptADCConfig->P.ClkSel; 00117 00118 /* Also enable corresponding Isrs */ 00119 tMyADC->IMR.B.MSKEOCTU = ptADCConfig->P.EOCTUIsrEn; 00120 tMyADC->IMR.B.MSKJEOC = ptADCConfig->P.JEOCIsrEn; 00121 tMyADC->IMR.B.MSKJECH = ptADCConfig->P.JEOCHIsrEn; 00122 tMyADC->IMR.B.MSKEOC = ptADCConfig->P.EOCIsrEn; 00123 tMyADC->IMR.B.MSKECH = ptADCConfig->P.EOCHIsrEn; 00124 /* If necessary, enable DMAs and define how they will be cleared */ 00125 tMyADC->DMAE.B.DCLR = ptADCConfig->P.DMAClrOnRead; 00126 tMyADC->DMAE.B.DMAEN = ptADCConfig->P.DMAEn; 00127 00128 /* Next, configure sampling speed for high-resolution channels */ 00129 /* Note that extended channels are not configured at all because */ 00130 /* Pictus only uses these channels. */ 00131 tMyADC->CTR[CLEAR].R = (uint32_t) (ptADCConfig->R.CTR); 00132 00133 /* Force the ADC into idle mode */ 00134 tMyADC->MCR.B.PWDN = CLEAR; 00135 } 00136 else 00137 { 00138 u8Status = ADC_ERR_BAD_INSTANCE; 00139 } 00140 00141 return (u8Status); 00142 } 00143 /* 00144 ****************************************************************************** 00145 * u8fnADCSelectRegIndex 00146 ****************************************************************************** 00147 */ 00148 static uint8_t u8fnADCSelectRegIndex(uint8_t u8Channel, uint16_t* pu16Mask) 00149 { 00150 *pu16Mask = (uint16_t)(BIT0 << (u8Channel % BITS_IN_32)); 00151 00152 return (u8Channel / BITS_IN_32); 00153 } 00154 /* 00155 ****************************************************************************** 00156 * u8fnADCChannelConfig 00157 ****************************************************************************** 00158 */ 00159 uint8_t u8fnADCChannelConfig(const ADCChConfig_t* tADCChConfig, 00160 const uint16_t* pu16Results) 00161 { 00162 /* Declare local variables */ 00163 uint8_t u8Status; 00164 uint16_t u16ChRegMask; 00165 uint8_t u8ChRegIndex; 00166 ADC_t tMyADC; 00167 00168 /* Init local variables */ 00169 u8Status = CLEAR; 00170 tMyADC = catADCInstanceList[(uint8_t) tADCChConfig->P.Instance]; 00171 00172 if(N_ELEMENTS(catADCInstanceList) > (uint8_t)tADCChConfig->P.Instance) 00173 { 00174 /* Make sure that the passed channel is a valid one */ 00175 if (ADC_CH_MAX >= tADCChConfig->P.Channel) 00176 { 00177 /* Make sure that there's no on-going conversion */ 00178 if (CLEAR == (ADC_ST_SAMPLE & tMyADC->MSR.B.ADCSTATUS)) 00179 { 00180 /* Make sure the module is not in low power mode - force it ON */ 00181 tMyADC->MCR.B.PWDN = CLEAR; 00182 00183 /* Figure out what the mask is for this particular channel */ 00184 u8ChRegIndex = u8fnADCSelectRegIndex( 00185 (uint8_t)tADCChConfig->P.Channel, (uint16_t*)&u16ChRegMask); 00186 00187 /* Enable this channel */ 00188 tMyADC->NCMR[u8ChRegIndex].R |= u16ChRegMask; 00189 00190 /* Now take care of ISR according to settings */ 00191 if (TRUE == tADCChConfig->P.ChIsrEn) 00192 { 00193 tMyADC->CIMR[u8ChRegIndex].R |= u16ChRegMask; 00194 /* Point the result to the right location */ 00195 gpu16ADCResults[((uint8_t) tADCChConfig->P.Instance * (ADC_CH_MAX 00196 + 1u)) + tADCChConfig->P.Channel] = (uint16_t*)pu16Results; 00197 } 00198 else 00199 { 00200 tMyADC->CIMR[u8ChRegIndex].R &= ~u16ChRegMask; 00201 } 00202 00203 /* Same thing for DMA */ 00204 if (TRUE == tADCChConfig->P.ChDMAEn) 00205 { 00206 tMyADC->DMAR[u8ChRegIndex].R |= u16ChRegMask; 00207 } 00208 else 00209 { 00210 tMyADC->DMAR[u8ChRegIndex].R &= ~u16ChRegMask; 00211 00212 /* If DMA is not enabled, it is a good idea to remember */ 00213 /* that we're supposed to be reading it in case CIMR is */ 00214 /* not set. We will do so next. */ 00215 gau16ADCChToRead[(uint8_t)tADCChConfig->P.Instance] 00216 |= u16ChRegMask; 00217 } 00218 } 00219 else 00220 { 00221 u8Status = ADC_ERR_ONGOING_CONV; 00222 } 00223 } 00224 else 00225 { 00226 u8Status = ADC_ERR_INVALID_CH; 00227 } 00228 } 00229 else 00230 { 00231 u8Status = ADC_ERR_BAD_INSTANCE; 00232 } 00233 00234 return (u8Status); 00235 } 00236 00237 /* 00238 ****************************************************************************** 00239 * u8fnADCReadChannel 00240 ****************************************************************************** 00241 */ 00242 uint8_t u8fnADCReadChannel(uint8_t u8Instance, uint8_t u8Channel, 00243 uint16_t* pu16ADCResult) 00244 { 00245 /* Declare local variables */ 00246 uint8_t u8Status; 00247 ADC_t tMyADC; 00248 00249 /* Init local variables */ 00250 u8Status = CLEAR; 00251 tMyADC = catADCInstanceList[u8Instance]; 00252 00253 /* If we have a correct instance */ 00254 if (N_ELEMENTS(catADCInstanceList) > u8Instance) 00255 { 00256 /* If we have valid data */ 00257 if (TRUE == tMyADC->CDR[u8Channel].B.VALID) 00258 { 00259 /* Copy the data to the pointer */ 00260 *pu16ADCResult = (uint16_t) tMyADC->CDR[u8Channel].B.CDATA; 00261 } 00262 else 00263 { 00264 /* We don't have valid data if we're here */ 00265 u8Status = ADC_ERR_INVALID_RESULT; 00266 } 00267 } 00268 else 00269 { 00270 /* We are pointing somewhere else. Don't continue */ 00271 u8Status = ADC_ERR_BAD_INSTANCE; 00272 } 00273 00274 return (u8Status); 00275 } 00276 00277 /* 00278 ****************************************************************************** 00279 * u8fnADCStatus 00280 ****************************************************************************** 00281 */ 00282 uint8_t u8fnADCStatus(uint8_t u8Instance) 00283 { 00284 /* Declare local variables */ 00285 uint8_t u8Status; 00286 00287 u8Status = (uint8_t)(catADCInstanceList[u8Instance]->MSR.B.ADCSTATUS); 00288 00289 return (u8Status); 00290 } 00291 /* 00292 ****************************************************************************** 00293 * u8fnADNormalConversionEnable 00294 ****************************************************************************** 00295 */ 00296 uint8_t u8fnADCNormalConversionEnable(uint8_t u8Instance, uint8_t u8Enable) 00297 { 00298 /* Declare local variables */ 00299 uint8_t u8Status; 00300 00301 /* Init Local Variables */ 00302 u8Status = CLEAR; 00303 00304 /* Continue only if pointer is valid */ 00305 if (N_ELEMENTS(catADCInstanceList) > u8Instance) 00306 { 00307 catADCInstanceList[u8Instance]->MCR.B.NSTART = (CLEAR < u8Enable); 00308 } 00309 else 00310 { 00311 /* We had an error */ 00312 u8Status = ADC_ERR_BAD_INSTANCE; 00313 } 00314 return (u8Status); 00315 } 00316 /* 00317 ****************************************************************************** 00318 * vfnADCEoCIsr 00319 ****************************************************************************** 00320 */ 00321 static void vfnADCEoCIsr(uint8_t u8Instance) 00322 { 00323 /* Declare local variables */ 00324 ADC_t tMyADC; 00325 vuint8_t u8Counter; 00326 uint16_t u16ChannelsToRead; 00327 00328 /* Init Local Variables */ 00329 tMyADC = catADCInstanceList[u8Instance]; 00330 u16ChannelsToRead = gau16ADCChToRead[u8Instance]; 00331 00332 switch (tMyADC->ISR.R) 00333 { 00334 case (ADC_ISR_EOCTU_MASK): 00335 { 00336 /* Something*/ 00337 break; 00338 } 00339 case (ADC_ISR_JEOC_MASK): 00340 { 00341 /* Something */ 00342 u8Counter = 1; 00343 break; 00344 } 00345 case (ADC_ISR_JECH_MASK): 00346 { 00347 /* Something */ 00348 u8Counter = 8; 00349 break; 00350 } 00351 case (ADC_ISR_EOC_MASK): 00352 { 00353 u8Counter = 3; 00354 break; 00355 } 00356 case (ADC_ISR_EOC_MASK | ADC_ISR_ECH_MASK): 00357 { 00358 /* Clear interrupt flag for EOC */ 00359 tMyADC->ISR.R |= ADC_ISR_EOC_MASK; 00360 /* Trickle down to the ECH case */ 00361 } 00362 case (ADC_ISR_ECH_MASK): 00363 { 00364 for (u8Counter = CLEAR; u8Counter < BITS_IN_16; u8Counter++) 00365 { 00366 if(BIT0 & u16ChannelsToRead) 00367 { 00368 00369 *gpu16ADCResults[(u8Instance * (ADC_CH_MAX + 1u)) + u8Counter] = (uint16_t)tMyADC->CDR[u8Counter].B.CDATA; 00370 00371 } 00372 else 00373 { 00374 /* Don't do anything */ 00375 } 00376 u16ChannelsToRead >>= 1u; 00377 } 00378 tMyADC->ISR.R |= ADC_ISR_ECH_MASK; 00379 break; 00380 } 00381 default: 00382 { 00383 /* Nothing happened */ 00384 } 00385 }; 00386 00387 return; 00388 } 00389 /* 00390 ****************************************************************************** 00391 * vfnADC0EoCIsr 00392 ****************************************************************************** 00393 */ 00394 void vfnADC0EoCIsr(void) 00395 { 00396 vfnADCEoCIsr(ADC_MODULE_0); 00397 return; 00398 } 00399 /* 00400 ****************************************************************************** 00401 * vfnADC1EoCIsr 00402 ****************************************************************************** 00403 */ 00404 void vfnADC1EoCIsr(void) 00405 { 00406 vfnADCEoCIsr(ADC_MODULE_1); 00407 return; 00408 } 00409 /* 00410 ****************************************************************************** 00411 * vfnADCErrIsr 00412 ****************************************************************************** 00413 */ 00414 static void vfnADCErrIsr(uint8_t u8Instance) 00415 { 00416 (void)u8Instance; 00417 return; 00418 } 00419 /* 00420 ****************************************************************************** 00421 * vfnADC0ErrIsr 00422 ****************************************************************************** 00423 */ 00424 void vfnADC0ErrIsr(void) 00425 { 00426 vfnADCErrIsr(ADC_MODULE_0); 00427 return; 00428 } 00429 /* 00430 ****************************************************************************** 00431 * vfnADC1ErrIsr 00432 ****************************************************************************** 00433 */ 00434 void vfnADC1ErrIsr(void) 00435 { 00436 vfnADCErrIsr(ADC_MODULE_1); 00437 return; 00438 } 00439 /* 00440 ****************************************************************************** 00441 * vfnADCWatchDogIsr 00442 ****************************************************************************** 00443 */ 00444 static void vfnADCWatchDogIsr(uint8_t u8Instance) 00445 { 00446 (void)u8Instance; 00447 return; 00448 } 00449 /* 00450 ****************************************************************************** 00451 * vfnADC0WatchDogIsr 00452 ****************************************************************************** 00453 */ 00454 void vfnADC0WatchDogIsr(void) 00455 { 00456 vfnADCWatchDogIsr(ADC_MODULE_0); 00457 return; 00458 } 00459 /* 00460 ****************************************************************************** 00461 * vfnADC1EoCTUIsr 00462 ****************************************************************************** 00463 */ 00464 void vfnADC1WatchDogIsr(void) 00465 { 00466 vfnADCWatchDogIsr(ADC_MODULE_1); 00467 return; 00468 } 00469 /* 00470 ****************************************************************************** 00471 * 00472 * End of file. 00473 * 00474 ****************************************************************************** 00475 */